package com.example.jasypt;

import cn.hutool.core.codec.Base64;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.symmetric.AES;
import org.jasypt.encryption.StringEncryptor;
import org.jasypt.encryption.pbe.PooledPBEStringEncryptor;
import org.jasypt.encryption.pbe.StandardPBEStringEncryptor;
import org.jasypt.encryption.pbe.config.EnvironmentStringPBEConfig;
import org.jasypt.encryption.pbe.config.SimpleStringPBEConfig;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringBootJasyptApplicationTest {


    private static final String PBEWITHMD5ANDDES = "PBEWithMD5AndDES";

    private static final String PBEWITHHMACSHA512ANDAES_256 = "PBEWITHHMACSHA512ANDAES_256";





    /**
     * @Description: Jasyp 加密（PBEWITHHMACSHA512ANDAES_256）
     * @Author:      Rambo
     * @CreateDate:  2020/7/25 14:34
     * @UpdateUser:  Rambo
     * @UpdateDate:  2020/7/25 14:34
     * @param		 plainText  待加密的原文
     * @param		 factor     加密秘钥
     * @return       java.lang.String
     * @Version:     1.0.0
     */
    public static String encryptWithSHA512(String plainText, String factor) {
        // 1. 创建加解密工具实例
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        // 2. 加解密配置
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(factor);
        config.setAlgorithm(PBEWITHHMACSHA512ANDAES_256);
        // 为减少配置文件的书写，以下都是 Jasyp 3.x 版本，配置文件默认配置
        config.setKeyObtentionIterations( "1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
        config.setStringOutputType("base64");
        encryptor.setConfig(config);
        // 3. 加密
        return encryptor.encrypt(plainText);
    }

    /**
     * @Description: Jaspy解密（PBEWITHHMACSHA512ANDAES_256）
     * @Author:      Rambo
     * @CreateDate:  2020/7/25 14:40
     * @UpdateUser:  Rambo
     * @UpdateDate:  2020/7/25 14:40
     * @param		 encryptedText  待解密密文
     * @param		 factor         解密秘钥
     * @return       java.lang.String
     * @Version:     1.0.0
     */
    public static String decryptWithSHA512(String encryptedText, String factor) {
        // 1. 创建加解密工具实例
        PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
        // 2. 加解密配置
        SimpleStringPBEConfig config = new SimpleStringPBEConfig();
        config.setPassword(factor);
        config.setAlgorithm(PBEWITHHMACSHA512ANDAES_256);
        // 为减少配置文件的书写，以下都是 Jasyp 3.x 版本，配置文件默认配置
        config.setKeyObtentionIterations( "1000");
        config.setPoolSize("1");
        config.setProviderName("SunJCE");
        config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
        config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
        config.setStringOutputType("base64");
        encryptor.setConfig(config);
        // 3. 解密
        return encryptor.decrypt(encryptedText);
    }
    public static void main(String[] args) {
        String factor = "yxw@2023";
        String plainText = "Busyxw@123!";
        String encryptWithMD5Str = encryptWithMD5(plainText, factor);
        String decryptWithMD5Str = decryptWithMD5(encryptWithMD5Str, factor);

        String encryptWithSHA512Str = encryptWithSHA512(plainText, factor);
        String decryptWithSHA512Str = decryptWithSHA512(encryptWithSHA512Str, factor);
        System.out.println("采用MD5加密前原文密文：" + encryptWithMD5Str);
        System.out.println("采用MD5解密后密文原文:" + decryptWithMD5Str);
        System.out.println();
        System.out.println("采用SHA512加密前原文密文：" + encryptWithSHA512Str);
        System.out.println("采用SHA512解密后密文原文:" + decryptWithSHA512Str);
    }
    /**
     * @Description: Jaspy解密（PBEWithMD5AndDES）
     * @Author:      Rambo
     * @CreateDate:  2020/7/13 10:28
     * @UpdateUser:  Rambo
     * @UpdateDate:  2020/7/13 10:28
     * @param		 encryptedText      待解密密文
     * @param		 factor             解密秘钥
     * @return       java.lang.String
     * @Version:     1.0.0
     */
    public static String decryptWithMD5(String encryptedText, String factor) {
        // 1. 创建加解密工具实例
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        // 2. 加解密配置
        EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
        config.setAlgorithm(PBEWITHMD5ANDDES);
        config.setPassword(factor);
        encryptor.setConfig(config);
        // 3. 解密
        return encryptor.decrypt(encryptedText);
    }
    /**
     * @Description: Jasyp加密（PBEWithMD5AndDES）
     * @Author:      Rambo
     * @CreateDate:  2020/7/13 10:24
     * @UpdateUser:  Rambo
     * @UpdateDate:  2020/7/13 10:24
     * @param		 plainText      待加密的原文
     * @param		 factor         加密秘钥
     * @return       java.lang.String
     * @Version:     1.0.0
     */
    public static String encryptWithMD5(String plainText, String factor) {
        // 1. 创建加解密工具实例
        StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
        // 2. 加解密配置
        EnvironmentStringPBEConfig config = new EnvironmentStringPBEConfig();
        config.setAlgorithm(PBEWITHMD5ANDDES);
        config.setPassword(factor);
        encryptor.setConfig(config);
        // 3. 加密
        return encryptor.encrypt(plainText);
    }

    private static final String PASSWORD = "password";
    private static final String KEY_ALGORITHM = "AES";

    @Resource
    private StringEncryptor stringEncryptor;

    /**
     * 加密
     */
    @Test
    public void encryptPwd() {
        String result = stringEncryptor.encrypt("test@dbuser2019");
        System.out.println("加密后的结果为：result=:"+result);
    }

    @Test
    public void encrypt() {
        String encrypt = stringEncryptor.encrypt("admin");
        String monitorPwd = stringEncryptor.encrypt("admin@123!");

        //UUID  加密后的内容：AkZs6tdmJojZe74vfIi5BRXbUvqkBiNQrn3RO22GeqW9sBjbNuIcNz+GdqkqJ8DQ
        System.out.println("admin：" + encrypt);
        System.out.println("admin@123!：" + monitorPwd);
        // 解密
        String decrypt = stringEncryptor.decrypt(encrypt);
        String decryptPwd = stringEncryptor.decrypt(monitorPwd);
        System.out.println("解密后的内容：" + decrypt);
        System.out.println("解密后的内容：" + decryptPwd);
    }


    @Test
    public void testJasypt() {
//		PasswordEncoder ENCODER = new BCryptPasswordEncoder();
//		System.out.println(ENCODER.encode("123456"));


        // 对应application-dev.yml 中配置的根密码
        System.setProperty("jasypt.encryptor.password", "yxw@123!");

        //加密方法
        System.out.println("加密方法:" + stringEncryptor.encrypt("yxw@123!"));
        System.out.println("Redis加密后密码为:" + stringEncryptor.encrypt("test@dbuser2022"));
        //解密方法
        System.out.println("解密方法:" + stringEncryptor.decrypt("kRmGb75VUsg2NruJCxM487yIzi9ZPbyE"));
    }

    /**
     * @param data 内容
     * @param pass 密码
     * @return
     * @throws Exception
     *
     * AES对称解密
     */
    private static String decryptAES(String data, String pass) {
        AES aes = new AES(Mode.CBC, Padding.NoPadding,
                new SecretKeySpec(pass.getBytes(), KEY_ALGORITHM),
                new IvParameterSpec(pass.getBytes()));
        byte[] result = aes.decrypt(Base64.decode(data.getBytes(StandardCharsets.UTF_8)));
        return new String(result, StandardCharsets.UTF_8);
    }
}
